import { Vector3, Raycaster } from "three";
import { App } from "../../../application";
import Events from "../../../application/constants/Events";
import MeshUtil from "../../../renderExtension/utils/MeshUtil";
import Helper from "../../../utils/Helper";

export default class AdjustHeight {
    private data: {mesh, falldownSurface};
    // private mesh;
    private groupBoundingBox; //模型的包围盒，该包围盒只在模型贴到特定物体上的时候才会生成
    private everSetHeight = false; //是否设置过模型的高度
    private debounceLoadEvent;

    public constructor(data: {mesh, falldownSurface}){ //mesh
        this.data = data;
        // this.mesh = mesh;

        // this.computeBoundingBox();
    }

    private computeBoundingBox(){ //计算模型的包围盒
        if(this.data.mesh && this.data.falldownSurface){
        // if(this.mesh){
            // 创建一个边界框，用于合并group中所有子对象的世界边界
            this.groupBoundingBox = MeshUtil.computeBox(this.data.mesh); //this.mesh
            // 将group的世界边界转换到视图空间
            let viewMatrix = App.getInstance().three.camera.matrixWorld;
            this.groupBoundingBox.applyMatrix4(viewMatrix);
        }
    }

    public startAdjust(){
        this.debounceLoadEvent = Helper.debounce2(this.adjustHeight.bind(this), 50, false);
        App.getInstance().on(Events.AdjustModelHeight, this.debounceLoadEvent, this);

        App.getInstance().fireEvent(Events.AdjustModelHeight, this.data.falldownSurface); //通知其他模型根据这个瓦片的数据调整高度
    }

    private adjustHeight(falldownSurface) {
        // if(!this.data.falldownSurface || !this.data.mesh){
        //     return;
        // }
        if(!this.data.mesh){ //this.mesh
            return;
        }
        if(!this.data.mesh.parent){
            App.getInstance().off(Events.AdjustModelHeight, this.debounceLoadEvent, this);
            this.data = null;
            return;
        }
        if(this.everSetHeight == true){
            return;
        }
        // let isVisible = App.getInstance().camera.checkVisible(this.groupBoundingBox);
        // if(isVisible){
        let rayDirection = new Vector3(0, 0, -1);
        let rayBeginPosition = this.data.mesh.position.clone(); //this.mesh
        rayBeginPosition.z = 1000000;
        let raycaster: Raycaster = new Raycaster(rayBeginPosition, rayDirection);
        try {
            let objArray = raycaster.intersectObject(falldownSurface, true); // this.data.falldownSurface
            if (objArray.length > 0) {
                this.data.mesh.position.z += objArray[0].point.z; //this.data.mesh
                this.data.mesh.updateMatrix();

                this.everSetHeight = true; //模型的高度已经被设置过了
                App.getInstance().off(Events.AdjustModelHeight, this.debounceLoadEvent, this);
            }
        } catch (error) {
            console.log(error);
        }
        
        // }
    }
}
